home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_500
/
wiconify
/
wiconify-source.lzh
/
Source
/
wHandler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-25
|
30KB
|
952 lines
/*
* WICONIFY A utility that allows you to iconify any Intuition window
* on any screen, and to open WB windows on any screen.
*
* wHandler.c The Input Handler and replacement routines for the
* Intuition functions trapped by SetFunction().
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#define INTUITION_PREFERENCES_H /* don't need 'em */
#include <intuition/intuitionbase.h>
#include "wHandler.h"
#include "wMenu.h"
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
/*
* The definition for wIconify BackDrop windows
* (the IDCMPFlags are added later, since they share a UserPort)
*/
static struct NewWindow BDWindow =
{
0,0, 0,0, -1,-1, NULL,
SIMPLE_REFRESH| NOCAREREFRESH| BACKDROP| BORDERLESS| REPORTMOUSE,
NULL, NULL, NULL, NULL, NULL, 20,20, -1,-1, WBENCHSCREEN
};
extern struct wMenuItem OpenWindowMenu[];
/*
* Tells whether a screen is iconified (i.e., pushed off the bottom)
*/
#define ISICONIFIED(s) ((s)->TopEdge > GfxBase->NormalDisplayRows)
/*
* CheckIconifiedScreen()
*
* If the front screen is iconified, move it to the back.
* If there is an active window
* If its screen is iconified
* Look for the next uniconified screen
* (Start over from the front of the list if we hit the end)
* If we found an uniconified screen and it has a window
* Activate the window
* (i.e, try to make sure that windows on iconified screens never become
* active. Give preference to forward screens rather than backward ones.
* This may effect the use of some hot-key screen shufflers that activate
* windows on the new front screen: pushing screens to the back will
* still work fine, but pulling the back one to the front will fail).
*/
static void CheckIconifiedScreen()
{
struct Screen *iScreen;
Forbid();
iScreen = IntuitionBase->FirstScreen;
if (ISICONIFIED(iScreen)) ScreenToBack(iScreen);
if (IntuitionBase->ActiveWindow)
{
iScreen = IntuitionBase->ActiveWindow->WScreen;
if (ISICONIFIED(iScreen))
{
while (iScreen && ISICONIFIED(iScreen)) iScreen = iScreen->NextScreen;
if (iScreen == NULL)
{
iScreen = IntuitionBase->FirstScreen;
while (iScreen && ISICONIFIED(iScreen))
iScreen = iScreen->NextScreen;
}
if (iScreen && iScreen->FirstWindow)
ActivateWindow(iScreen->FirstWindow);
}
}
Permit();
}
/*
* wHandler()
*
* If we are in the process of ending, just return the list
* Check for iconified screens
* While there are events in the list
* If they are mouse or key events
* If the event matches the iconify-key specification (up or down)
* If the event is the key or button up event
* Get a new message to send to the wIconify process
* Set up the values to pass to it
* Send it to the handler process
* Remove this event from the list
* (ie, process key-up events, but just remove key-down events)
* Otherwise, if the event matches the activation-key specification
* If it's the key up event
* Get the current active screen
* Activate its wIconify window, if any
* Remove this event from the list (as above)
* If we are removing the event from the list, do so
* Go on to the next event in the list
* Return the (modified) list.
*/
struct InputEvent *wHandler(EventList,data)
struct InputEvent *EventList;
APTR data;
{
struct InputEvent **EventPtr = &EventList;
struct InputEvent *theEvent;
struct wIconMessage *theMessage;
WSCREEN *theScreen;
int RemoveEvent = FALSE;
if (EndSignal) return(EventList);
CheckIconifiedScreen();
while (theEvent = *EventPtr)
{
if (theEvent->ie_Class == IECLASS_RAWMOUSE ||
theEvent->ie_Class == IECLASS_RAWKEY)
{
if ((theEvent->ie_Code | IECODE_UP_PREFIX) == IconifyKey &&
(theEvent->ie_Qualifier & (IconifyQuals | IconifyDisquals))
== IconifyQuals)
{
if (theEvent->ie_Code == IconifyKey)
{
if (NEWSTRUCT(wIconMessage,theMessage))
{
theMessage->Window = IntuitionBase->ActiveWindow;
theMessage->Action = WI_ICONIFY;
theMessage->Flags = WI_NOREPLY;
if ((theEvent->ie_Qualifier & IconifyChange) == IconifyChange)
theMessage->Flags |= WI_CHANGE;
theMessage->Message.mn_ReplyPort = NULL;
theMessage->Message.mn_Length = sizeof(struct wIconMessage);
PutMsg(wIconPort,theMessage);
}
}
RemoveEvent = TRUE;
} else if ((theEvent->ie_Code | IECODE_UP_PREFIX) == ActivateKey &&
(theEvent->ie_Qualifier & ActivateQuals) == ActivateQuals) {
if (theEvent->ie_Code == ActivateKey)
{
Forbid();
theScreen = FindScreen(IntuitionBase->ActiveScreen);
if (theScreen && theScreen->BackDrop)
ActivateWindow(theScreen->BackDrop);
Permit();
}
RemoveEvent = TRUE;
}
}
if (RemoveEvent)
*EventPtr = theEvent->ie_NextEvent;
else
EventPtr = &(theEvent->ie_NextEvent);
RemoveEvent = FALSE;
}
return(EventList);
}
#define TOUPPER(c) (((c)>='a'&&(c)<='z')?(c)-'a'+'A':c)
/*
* PrefixMatch()
*
* Case-insensitive prefix match. The empty string will match NULL pointers
* and empty strings, but are not considered prefixes to any string.
*
* Return <0 if the first is smaller than the second,
* =0 if the first is a prefix of the second,
* >1 if the first is larger than the second.
*/
int PrefixMatch(s1,s2)
char *s1,*s2;
{
int match = -1;
if (*s1)
{
if (s2)
{
while (TOUPPER(*s1) == TOUPPER(*s2) && *s2 != 0) s1++,s2++;
if (*s1 == 0) match = 0; else match = *s1 - *s2;
} else match = 1;
} else if (s2 == NULL || *s2 == 0) match = 0;
return(match);
}
/*
* GetScreen()
*
* Find the screen where the window will open via the following rules:
* If we are supposed to open on the active screen, get the active screen
* Otherwise, if we are supposed to open on the current WB, get it
* If we have found a screen
* If the screen is the real WB, forget it (no changes needed)
* If the screen is closing or iconified, forget it
* If the screen we are opening on is not currently active
* Get the actual screen pointer of the screen we are interested in
* If it is not active, we should bring it to the front
* return the WSCREEN we shoulod use (or NULL if no action)
*/
static WSCREEN *GetScreen(BringToFront)
int *BringToFront;
{
WSCREEN *theScreen = NULL;
struct Screen *chkScreen = NULL;
if (OpenWindowMenu[OW_ACTIVESCRN].Item.Flags & CHECKED)
theScreen = FindScreen(IntuitionBase->ActiveScreen); else
if (OpenWindowMenu[OW_CURRENTWB].Item.Flags & CHECKED)
theScreen = WBScreen;
if (theScreen)
{
if (theScreen == RealWB) theScreen = NULL; else
if ((theScreen->Flags & WI_CLOSING) ||
(theScreen->Icon.Icon.Flags & WI_ICONIFIED))
theScreen = NULL;
}
if (theScreen) chkScreen = theScreen->Screen;
else if (RealWB) chkScreen = RealWB->Screen;
*BringToFront = (chkScreen != IntuitionBase->ActiveScreen);
return(theScreen);
}
/*
* CheckWindowSize()
*
* If the window has a drag bar
* Check if it fits on the screen; if not, move it to a better spot
* If the window has a sizing gadget or accepts NEWSIZE messages
* If the window doesn't fint on the screen, shrink it so that it does
* Return an indication of whether the size was modified
*/
static int CheckWindowSize(newWindow)
struct NewWindow *newWindow;
{
short x = newWindow->LeftEdge;
short y = newWindow->TopEdge;
short w = newWindow->Width;
short h = newWindow->Height;
short Sw = newWindow->Screen->Width;
short Sh = newWindow->Screen->Height;
int Sized = FALSE;
if (newWindow->Flags & WINDOWDRAG)
{
if (x+w > Sw) x = newWindow->LeftEdge = (Sw > w)? Sw - w: 0;
if (y+h > Sh) y = newWindow->TopEdge = (Sh > h)? Sh - h: 0;
}
if ((newWindow->Flags & WINDOWSIZING) || (newWindow->IDCMPFlags & NEWSIZE))
{
if (x < Sw && x+w > Sw) newWindow->Width = Sw - x, Sized = TRUE;
if (y < Sh && y+h > Sh) newWindow->Height = Sh - y, Sized = TRUE;
}
return(Sized);
}
/*
* cOpenWindow()
*
* If we have a new window and we are not in the process of ending Iconify
* Get the screen where we should open, and the bring-to-front flag
* If we have a screen to open on, and the window was opening on the WB
* Get a new wbWindow structure for it
* Copy the NewWindow info so we can change it
* Change the window specification so that it opens on the right screen
* If we are allowed to resize the window, check if it needs it
* Try to open the window
* If successful
* Link the window into the screen's list of foreign windows
* Send a resize message if the window was sized
* Otherwise
* Free the allocated structure (we won't be needing it)
* Otherwise (it's not a window we're supposed to change)
* If the real WB screen is open and this window is the WB backdrop
* window (ie, LoadWB is trying to start the WB)
* Copy the NewWindow structure so we can "fix" it
* Set the width to something smaller
* Move the window to the right side of the screen
* Make it a regular non-backdrop window with a border
* Add the sizing, dragging and depth gadgets
* Then open the window
* If the window was not opened yet, open it as a normal window
* If we are supposed to bring a screen to the front and the window
* was actually opened, bring the screen to front
* Return the pointer to the opened window
*/
struct Window *cOpenWindow(newWindow)
struct NewWindow *newWindow;
{
struct Window *theWindow = NOWINDOW;
struct NewWindow tmpWindow;
WBWINDOW *WBWindow;
WSCREEN *theScreen = NULL;
int BringToFront = FALSE;
int Sized = FALSE;
if (newWindow && EndSignal == 0)
{
Forbid();
theScreen = GetScreen(&BringToFront);
if (theScreen && (newWindow->Type & SCREENTYPE) == WBENCHSCREEN)
{
if (NEWSTRUCT(wbWindow,WBWindow))
{
tmpWindow = *newWindow;
tmpWindow.Screen = theScreen->Screen;
tmpWindow.Type = CUSTOMSCREEN;
if (OpenWindowMenu[OW_AUTORESIZE].Item.Flags & CHECKED)
Sized = CheckWindowSize(&tmpWindow);
theWindow = aOldOpenWindow(&tmpWindow);
if (theWindow)
{
WBWindow->Window = theWindow;
LinkWindow(WBWindow,theScreen);
if (Sized) SendIntuiMessage(NEWSIZE,theWindow);
} else {
FREESTRUCT(wbWindow,WBWindow);
}
}
} else if (RealWB && (newWindow->Flags & WBFLAGS) == WBFLAGS) {
tmpWindow = *newWindow;
tmpWindow.Width = WBWIDTH;
tmpWindow.LeftEdge = RealWB->Screen->Width - WBWIDTH;
tmpWindow.Flags &= ~(BORDERLESS | BACKDROP);
tmpWindow.Flags |= WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH;
theWindow = aOldOpenWindow(&tmpWindow);
}
Permit();
}
if (theWindow == NOWINDOW) theWindow = aOldOpenWindow(newWindow);
if (BringToFront && theWindow != NOWINDOW) ScreenToFront(theWindow->WScreen);
return(theWindow);
}
/*
* ParentWindow()
*
* Get the parent window of the current one
* If it has one, then
* Find its icon
* While the window we are looking at is iconified
* Go to its parent and get its icon
* If we did not find a window, use the screen's backdrop window
* Return the window that we found
*/
static struct Window *ParentWindow(theWindow)
struct Window *theWindow;
{
WICONREF *theIcon;
WSCREEN *theScreen = NULL;
theWindow = theWindow->Parent;
if (theWindow)
{
theIcon = FindIcon(theWindow,&theScreen);
while (theIcon && (theIcon->Icon.Flags & WI_ICONIFIED))
{
theWindow = theWindow->Parent;
theIcon = (theWindow)? FindIcon(theWindow,&theScreen): NULL;
}
}
if (theWindow == NULL && theScreen) theWindow = theScreen->BackDrop;
return(theWindow);
}
/*
* FinishWindow()
*
* Find the icon of the window that is closing
* If it has one, tell the Iconify process to remove it
* Find the wbWindow structure of this window (if any)
* If it has one (ie, it is opened on a foreign screen)
* Unlink the window from the screen
* If it was the last one on the screen, let the Iconify process know
* (it may want to update the menu to include CLOSESCREEN)
* Free the window structure
* If the Iconify process was waiting to end, let it try now
* Find the (first non-iconified) parent of this window
* Close the window
* If the screen was waiting to close, signal it that it can
* Of Iconify wants to hear about this window, signal it
* If Intuition would attempt to activate an iconified window,
* Activate the first non-iconified parent window
*/
static void FinishWindow(oldWindow,RemoveWindow)
struct Window *oldWindow;
void (*RemoveWindow)();
{
WBWINDOW *theWindow;
APTR ScreenTask = NULL;
ULONG ScreenSignal;
ULONG IconSignal = 0;
WICONREF *theIcon;
WSCREEN *theScreen;
struct Window *Parent,*OldParent;
Forbid();
theIcon = FindIcon(oldWindow,&theScreen);
if (theIcon) SendIconMessage(WI_REMOVEICON,NULL,theScreen,theIcon);
theWindow = FindWindow(oldWindow);
if (theWindow)
{
ScreenTask = theWindow->Screen->CloseTask;
ScreenSignal = theWindow->Screen->CloseSignal;
UnLinkWindow(theWindow);
if (theWindow->Screen->Window == NULL) IconSignal = CloseSignal;
FREESTRUCT(wbWindow,theWindow);
IconSignal |= EndSignal;
}
Parent = ParentWindow(oldWindow); OldParent = oldWindow->Parent;
Permit();
(*RemoveWindow)(oldWindow);
if (ScreenTask) Signal(ScreenTask,ScreenSignal);
if (IconSignal) Signal(IconTask,IconSignal);
if (Parent && Parent != OldParent) ActivateWindow(Parent);
}
/*
* cCloseWindow()
*
* We are finished with this window; use the old CloseWindow() routine
* to remove it from the screen.
*/
void cCloseWindow(oldWindow)
struct Window *oldWindow;
{
extern void aOldCloseWindow();
FinishWindow(oldWindow,&aOldCloseWindow);
}
/*
* cOpenScreen()
*
* If the screen was opened OK, and the Iconify process is not ending
* Look through the ignore-screen list for this screen
* If it does not appear in the list
* Get a new Screen sctructure for this screen
* Open a BackDrop window of the correct size on this screen
* Set up the screen's icon
* If the BackDrop window opened OK
* Link the screen into the list
* Set the new window as the current WB window
* else
* Free the structure, we won't be needing it
*/
void cOpenScreen(newScreen)
struct Screen *newScreen;
{
WSCREEN *theScreen;
struct Ignore *igScreen = IgnoreScreen;
extern struct Window *OpenWindow();
extern struct Menu wMenu[];
if (newScreen && EndSignal == 0)
{
while (igScreen && PrefixMatch(igScreen->Title,newScreen->DefaultTitle))
igScreen = igScreen->Next;
if (igScreen == NULL)
{
if (NEWSTRUCT(wScreen,theScreen))
{
theScreen->Screen = newScreen;
BDWindow.Screen = newScreen;
BDWindow.Type = newScreen->Flags & SCREENTYPE;
BDWindow.Width = newScreen->Width;
BDWindow.Height = newScreen->Height;
theScreen->BackDrop = OpenWindow(&BDWindow);
theScreen->Icon.Icon.Name = newScreen->DefaultTitle;
theScreen->Icon.Icon.Flags = WI_SCREENICON| DefaultScreenFlags;
theScreen->Icon.Screen = theScreen;
theScreen->Icon.Window = theScreen->BackDrop;
if (theScreen->BackDrop)
{
LinkScreen(theScreen);
NewIconWindow(theScreen);
} else {
FREESTRUCT(wScreen,theScreen);
}
}
}
}
}
/*
* cCloseScreen()
*
* Look to see if the screen is in the list of screens with wIconify windows
* If so,
* Mark the screen as closing so we don't allow any more icons on it
* If the screen is the current WB, clear the current WB
* If the screen is the real WB screen (should never happen), forget it
* Restore the screen's icon if it is iconified
* Tell anyone who's interested that the screen is closing
* Remove any icons we're allowed to remove
* Wait for any foreign windows or other icons to be removed
* If the current task is the wIconify handler process, unlink the screen
* Otherwise send wIconify the message to remove the screen
* Close the wIconify backdrop window
* Close the screen itself and free the screen structure
* Otherwise
* Just close the screen
*/
void cCloseScreen(oldScreen)
struct Screen *oldScreen;
{
WSCREEN *theScreen;
Forbid();
theScreen = FindScreen(oldScreen);
if (theScreen)
{
theScreen->Flags |= WI_CLOSING;
if (theScreen == WBScreen) NewWBScreen(NULL);
if (theScreen == RealWB) RealWB = NULL;
Permit();
Restore(&(theScreen->Icon),TRUE);
ReportMulti(WI_REPORTSCREENCLOSE,theScreen->Screen,theScreen);
RemoveAutoIcons(theScreen);
WaitForWindows(theScreen);
if (FindTask(NULL) == IconTask)
UnLinkScreen(theScreen);
else
SendIconMessage(WI_REMSCREEN,NULL,theScreen,NULL);
CloseIconWindow(theScreen);
aOldCloseScreen(oldScreen);
FREESTRUCT(wScreen,theScreen);
} else {
Permit();
aOldCloseScreen(oldScreen);
}
}
/*
* cSetWindowTitles()
*
* If a window was specified and it is getting a new title
* Look for the window's icon
* If found, and if the icon has a gadget (ie, it is iconified)
* Set the icon's title and center it
* Tell wIconify to update the screen
*/
void cSetWindowTitles(theWindow,wTitle,sTitle)
struct Window *theWindow;
UBYTE *wTitle,*sTitle;
{
WICONREF *theIcon;
WSCREEN *theScreen;
if (theWindow && wTitle != (UBYTE *)-ONE)
{
Forbid();
theIcon = FindIcon(theWindow,&theScreen);
if (theIcon && theIcon->Gadget)
{
theIcon->Gadget->IText.IText = (wTitle)? wTitle: "[No Title]";
theIcon->Gadget->IText.LeftEdge =
(((struct Image *)(theIcon->Gadget->Gadget.GadgetRender))->Width -
IntuiTextLength(&theIcon->Gadget->IText)) / 2;
SendIconMessage(WI_REDRAW,NULL,theIcon->Screen,NULL);
}
Permit();
}
}
/*
* cWindowToFront()
*
* If a window was specified and it is a BACKDROP window
* If the current task is not the wIconify handler process
* Find the icon for this window
* If it was found and it is iconified, or if its screen was found
* and the window is the wIconify backdrop window, don't allow the
* window to be moved
* Return TRUE if the window can be moved, FLASE otherwise
*/
int cWindowToFront(theWindow)
struct Window *theWindow;
{
int MoveIt = TRUE;
WICONREF *theIcon;
WSCREEN *theScreen;
if (theWindow && (theWindow->Flags & BACKDROP))
{
if (FindTask(NULL) != IconTask)
{
theIcon = FindIcon(theWindow,&theScreen);
if ((theIcon && (theIcon->Icon.Flags && WI_ICONIFIED)) ||
(theScreen && theScreen->BackDrop == theWindow)) MoveIt = FALSE;
}
}
return(MoveIt);
}
/*
* cWindowToBack()
*
* If a window was specified and it is a BACKDROP window
* If the current task is not the wIconify handler process
* Find the icon for this window
* If it was found and it is iconified, or if its screen was found
* and the window is the wIconify backdrop window, don't allow the
* window to be moved
* Otherwise, the window is a BACKDROP window that is being
* sent to the back, so it will fall behind the wIconify window
* were the user will not be able to get at it, so iconify it
* so it can be retrieved.
* Return TRUE if the window can be moved, FLASE otherwise
*/
int cWindowToBack(theWindow)
struct Window *theWindow;
{
int MoveIt = TRUE;
WICONREF *theIcon;
WSCREEN *theScreen;
if (theWindow && (theWindow->Flags & BACKDROP))
{
if (FindTask(NULL) != IconTask)
{
theIcon = FindIcon(theWindow,&theScreen);
if ((theIcon && (theIcon->Icon.Flags & WI_ICONIFIED)) ||
(theScreen && theScreen->BackDrop == theWindow)) MoveIt = FALSE;
else SendIconMessage(WI_ICONIFY,theWindow,NULL,NULL);
}
}
return(MoveIt);
}
/*
* cActivateWindow()
*
* If a window was specified and it is a BACKDROP window
* If the current process is not the wIconify process
* Find the icon for this window
* If found and it is iconified, don't all the window to be activated
* Return TRUE if it can be activated, FALSE otherwise
*/
int cActivateWindow(theWindow)
struct Window *theWindow;
{
int Activate = TRUE;
WICONREF *theIcon;
WSCREEN *theScreen;
if (theWindow && (theWindow->Flags & BACKDROP))
{
if (FindTask(NULL) != IconTask)
{
theIcon = FindIcon(theWindow,&theScreen);
if (theIcon && (theIcon->Icon.Flags & WI_ICONIFIED)) Activate = FALSE;
}
}
return(Activate);
}
/*
* cBuildSysRequest()
*
* If wIconify is stil running
* If a window was not specified
* Get the process that is calling BuildSysRequest()
* If it is really a process and it has an error window, use it
* If there is still no window
* Get the screen and bring-to-front flag as for normal windows
* If it is for a different screen, use it's backdrop window
* If we have a window to work with
* If we don't already have a screen, get it
* If the screen is the real WB, ignore it
* If we got a screen
* Allocate a new wbWindow structure
* If this fails, use the original window (ie, don't switch its screen)
* Get the system requester on the proper screen
* If we actually got a window (not TRUE or FALSE)
* If we have a wbWindow for this window, link it in
* Bring the screen to the front, if necessary
* If the process has a name, use it as the window title
* Otherwise use "System Request" as usual
* Otherwise, free the wbWindow, if it was allocated
* Return the window created by the original BuildSysRequest
*/
struct Window *cBuildSysRequest(theWindow,Body,PosText,NegText,Flags,w,h)
struct Window *theWindow;
struct IntuiText *Body,*PosText,*NegText;
ULONG Flags;
long w,h;
{
extern struct Window *aOldBuildSysRequest();
struct Process *theProc = NULL;
struct Window *onWindow = theWindow;
struct Window *newWindow;
WBWINDOW *WBWindow = NULL;
WSCREEN *theScreen = NULL;
int BringToFront = FALSE;
char *theTitle;
Forbid();
if (EndSignal == 0)
{
if (onWindow == NULL)
{
theProc = (struct Process *)FindTask(NULL);
if (theProc->pr_Task.tc_Node.ln_Type == NT_PROCESS &&
theProc->pr_WindowPtr != (APTR)-1)
onWindow = (struct Window *)theProc->pr_WindowPtr;
if (onWindow == NULL)
{
theScreen = GetScreen(&BringToFront);
if (theScreen) onWindow = theScreen->BackDrop;
}
}
if (onWindow)
{
if (theScreen == NULL) theScreen = FindScreen(onWindow->WScreen);
if (theScreen == RealWB) theScreen = NULL;
if (theScreen)
if (NEWSTRUCT(wbWindow,WBWindow) == NULL) onWindow = theWindow;
}
}
newWindow = aOldBuildSysRequest(onWindow,Body,PosText,NegText,Flags,w,h);
if (newWindow && newWindow != (struct Window *)TRUE)
{
if (WBWindow)
{
WBWindow->Window = newWindow;
LinkWindow(WBWindow,theScreen);
}
if (BringToFront) ScreenToFront(newWindow->WScreen);
if (theProc && theProc->pr_Task.tc_Node.ln_Name)
theTitle = theProc->pr_Task.tc_Node.ln_Name;
else
theTitle = "System Request";
SetWindowTitles(newWindow,theTitle,-1L);
} else {
if (WBWindow) FREESTRUCT(wbWindow,WBWindow);
}
Permit();
return(newWindow);
}
/*
* cFreeSysRequest()
*
* We are finished with this requester; use the old FreeSysRequest() routine
* to remove it from the screen.
*/
void cFreeSysRequest(oldWindow)
struct Window *oldWindow;
{
extern void aOldFreeSysRequest();
FinishWindow(oldWindow,&aOldFreeSysRequest);
}
/*
* cAutoRequest()
*
* Use (the modified) BuildSysRequest() to get a system requester
* If we got a window (not TRUE or FALSE)
* Get the signal bit for the window's port
* While we are not done with the requester
* While there are more messages in the port
* Get the message info and reply to the message
* If the message is one of the positive ones, end with TRUE
* If it is one of the negative ones, end with FALSE
* If it is a key event and the left amiga key id down
* If it is left-amiga-B, cancel the requester
* If it is left-amiga-V, retry the requester
* If it is a gadget event
* If the gadget is the negative one, end with FALSE
* If it is the positive one, end with TRUE
* If we are not done yet, Wait() for more messages
* Finish up the system requester
* Otherwise return the answer obtained from BuildSysRequest()
* Return the result (TRUE or FALSE)
*/
int cAutoRequest(theWindow,Body,PosText,NegText,PFlags,NFlags,w,h)
struct Window *theWindow;
struct IntuiText *Body,*PosText,*NegText;
ULONG PFlags,NFlags;
long w,h;
{
struct Window *newWindow;
struct IntuiMessage *theMessage;
struct Gadget *theGadget;
ULONG Signal,Class;
USHORT Code,Qual;
int Result = NOTDONE;
extern struct IntuiMessage *GetMsg();
extern struct Window *BuildSysRequest();
newWindow = BuildSysRequest(theWindow,Body,PosText,NegText,
GADGETUP|RAWKEY|PFlags|NFlags,w,h);
if (newWindow && newWindow != (struct Window *)TRUE)
{
Signal = (1 << newWindow->UserPort->mp_SigBit);
while (Result == NOTDONE)
{
while (theMessage = GetMsg(newWindow->UserPort))
{
Class = theMessage->Class;
Code = theMessage->Code;
Qual = theMessage->Qualifier;
theGadget = (struct Gadget *)theMessage->IAddress;
ReplyMsg(theMessage);
if (Class & PFlags) Result = TRUE; else
if (Class & NFlags) Result = FALSE; else
if (Class == RAWKEY && (Qual & AMIGALEFT))
{
if (Code == KEYCODE_B) Result = FALSE; else
if (Code == KEYCODE_V) Result = TRUE;
} else if (Class == GADGETUP) {
if (theGadget->GadgetText == NegText) Result = FALSE; else
if (theGadget->GadgetText == PosText) Result = TRUE;
}
}
if (Result == NOTDONE) Wait(Signal);
}
FreeSysRequest(newWindow);
} else Result = (int) newWindow;
return(Result);
}
/*
* SendIconMessage()
*
* Set up the data for the IconMessage
* If the current task is the wIconify process
* Call the event routine with the dummy message
* Otherwise
* Create a reply port
* If successful
* Set the message reply port
* Send the message to the wIconify process
* Wait for the reply
* Remove the port
*/
void SendIconMessage(theAction,theWindow,theScreen,theIcon)
int theAction;
struct Window *theWindow;
WSCREEN *theScreen;
WICONREF *theIcon;
{
struct wIconMessage theMessage;
struct MsgPort *thePort;
extern struct wIconMessage *WaitPort();
extern struct MsgPort *CreatePort();
theMessage.Window = theWindow;
theMessage.Icon = theIcon;
theMessage.Action = theAction;
theMessage.Flags = 0;
theMessage.Data.wScreen = theScreen;
if (FindTask(NULL) == IconTask)
{
DoIconEvent(&theMessage,TRUE);
} else {
thePort = CreatePort(NULL);
if (thePort)
{
theMessage.Message.mn_ReplyPort = thePort;
theMessage.Message.mn_Length = sizeof(struct wIconMessage);
PutMsg(wIconPort,&theMessage);
WaitPort(thePort);
DeletePort(thePort);
}
}
}
/*
* SendIntuiMessage()
*
* If the window has a message port and it accepts this type of message
* Allocate a new IntuiMessage structure
* If successful
* Set the important IntuiMessage fields
* Use the wIconify UserPort as the reply port (the wIconify process
* will clean up after us)
* Send the message to the window
*/
void SendIntuiMessage(theClass,theWindow)
ULONG theClass;
struct Window *theWindow;
{
struct IntuiMessage *theMessage;
if (theWindow && theWindow->UserPort && (theWindow->IDCMPFlags & theClass))
{
if (NEWSTRUCT(IntuiMessage,theMessage))
{
theMessage->Class = theClass;
theMessage->Qualifier = 0;
theMessage->Code = 0;
theMessage->MouseX = theMessage->MouseY = 0;
theMessage->IAddress = NULL;
theMessage->IDCMPWindow = theWindow;
theMessage->SpecialLink = NULL;
theMessage->ExecMessage.mn_ReplyPort = wUserPort;
theMessage->ExecMessage.mn_Length = sizeof(struct IntuiMessage);
PutMsg(theWindow->UserPort,theMessage);
}
}
}